package com.binance.gateway.util;

import com.binance.master.utils.StringUtils;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.log4j.Log4j2;

import javax.servlet.http.HttpServletResponse;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * Created by Raynold on 2018/10/30.
 * <p>
 * CallBackUrl验证工具类
 */
@Log4j2
public class CallBackUtil {

    private static final String DOT = ".";

    /**
     * 判断CallbackUrl是否合法
     *
     * @param callbackUrl
     * @param response
     * @param callbackDomainWhiteList
     * @return
     */
    public static void checkCallbackUrl(String callbackUrl, HttpServletResponse response, String callbackDomainWhiteList) throws ZuulException {
        if (StringUtils.isBlank(callbackUrl)) {
            return;
        }
        if (callbackUrl.contains("@") || callbackUrl.contains("\\")) {
            illegalCallbackUrlHandler(callbackUrl, response);
        }

        if (!callbackUrl.startsWith("http")) {
            startWithSlashHandler(callbackUrl, response);
            return;
        }

        normalHandler(callbackUrl, response, callbackDomainWhiteList);
    }

    private static void startWithSlashHandler(String callbackUrl, HttpServletResponse response) throws ZuulException {
        String relativeUrlPattern = "^/$|^(/[\\w.?&=-]+[/\\w.?&=-]*)$";

        if (callbackUrl.matches(relativeUrlPattern)) {
            return;
        }
        illegalCallbackUrlHandler(callbackUrl, response);
    }

    private static void normalHandler(String callbackUrl, HttpServletResponse response, String callbackDomainWhiteList) throws ZuulException {
        String[] whiteListArray = callbackDomainWhiteList.split(",");
        try {
            URL callback = new URL(callbackUrl);
            String callbackUrlDomain = callback.getHost();
            for (String validDomain : whiteListArray) {
                if (validDomain.contains("zendesk.com")) {
                    if (callbackUrlDomain.equals(validDomain)) {
                        return;
                    }
                } else {
                    validDomain = DOT + validDomain;
                    if (callbackUrlDomain.endsWith(validDomain)) {
                        return;
                    }
                }
            }
            illegalCallbackUrlHandler(callbackUrl, response);
        } catch (MalformedURLException e) {
            illegalCallbackUrlHandler(callbackUrl, response);
        }
    }

    private static void illegalCallbackUrlHandler(String callbackUrl, HttpServletResponse response) throws ZuulException {
        log.warn("Illegal callbackUrl:{}", callbackUrl);
        FilterUtil.badRequest(response);
    }
}
